package com.company.dcm.server.tcp;
import com.company.dcm.common.SpringBeanUtil;
import com.company.dcm.controller.OTAController;
import com.company.dcm.entity.R_ClothSheetDetail;
import com.company.dcm.mapper.MES_EquipIpMapper;
import com.company.dcm.server.protocol.ProtocolMessage;
import com.company.dcm.server.protocol.ProtocolMessageDecoder;
import com.company.dcm.server.protocol.ProtocolMessageEncoder;
import com.company.dcm.server.protocol.ProtocolTask;
import com.company.dcm.server.protocol.enums.ProtocolMessageTypeEnum;
import com.company.dcm.service.Device_otaService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

@Slf4j
@Component
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    @Autowired
    MES_EquipIpMapper mesEquipIpMapper;


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("9989 port");
        log.info(msg.toString());
        if (msg instanceof ByteBuf) {
            ByteBuf byteBuf = (ByteBuf) msg;
            System.out.println("Ip:" +  ctx.channel().remoteAddress().toString());
            System.out.println("ByteBuf content: ");
            for (int i = 0; i < byteBuf.readableBytes(); i++) {
                System.out.print(byteBuf.getByte(i) + " ");
            }
            System.out.println();
            for (int i = 0; i < byteBuf.readableBytes(); i++) {
                System.out.print(String.format("%02X ", byteBuf.getByte(i) & 0xFF));
            }
            System.out.println();
            ProtocolMessage message = new ProtocolMessage();
            try {
                message = ProtocolMessageDecoder.decode(byteBuf);
            } catch (IOException e) {
                e.printStackTrace();
                ctx.close();
                return;
            }
            byte[] responseData;
            try {
                responseData = handleRequest(ctx,message);
            } catch (IOException e) {
                e.printStackTrace();
                ctx.close();
                return;
            }
            ByteBuf response = Unpooled.wrappedBuffer(responseData);
            ctx.writeAndFlush(response);
        } else {
            System.err.println("Received unexpected message type: " + msg.getClass());
            ctx.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 异常处理
        cause.printStackTrace();
        ctx.close();
    }
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        String clientId = ctx.channel().remoteAddress().toString();
        ConnectionManager.addChannel(clientId, ctx.channel());

        System.out.println("Client connected: " + clientId);
    }
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        String ipPort = ctx.channel().remoteAddress().toString();
        String serial = ConnectionManager.ipPortToSerial.get(ipPort);
        if(serial!=null){
            ConnectionManager.serialToIpPort.remove(serial);
            ConnectionManager.ipPortToSerial.remove(ipPort);
        }

        Device_otaService deviceOtaService = SpringBeanUtil.getBean(Device_otaService.class);

        deviceOtaService.moveDevice(ipPort.split(":")[0]);

        ConnectionManager.removeChannel(ipPort);
        System.out.println("Client disconnected: " + ipPort);
    }
    private byte[] handleRequest(ChannelHandlerContext ctx, ProtocolMessage protocolMessage) throws IOException {
        log.info(protocolMessage.toString());
        List<ProtocolTask> tasks = protocolMessage.getBody();
        ProtocolMessageTypeEnum type = protocolMessage.getHeader().getType();
        TCPService tcpService = SpringBeanUtil.getBean("TCPService");
        OTAController otaController = SpringBeanUtil.getBean("OTAController");
        R_ClothSheetDetail r_clothSheetDetail = new R_ClothSheetDetail();//用来上传瑕疵详细信息的
        byte[] response = new byte[]{0};
        boolean hasMessage = false;
        ProtocolMessageEncoder encoder;
        if(type==ProtocolMessageTypeEnum.INFORMATION)
             encoder = new ProtocolMessageEncoder((byte) 1);
        else if (type == ProtocolMessageTypeEnum.BIG_DATA)
            encoder = new ProtocolMessageEncoder((byte) 2);
        else if(type==ProtocolMessageTypeEnum.OTA)
            encoder = new ProtocolMessageEncoder((byte) 3);
        else encoder = new ProtocolMessageEncoder((byte) 4);
        for (ProtocolTask task : tasks) {
            if(type == ProtocolMessageTypeEnum.INFORMATION){
                switch (task.getOption()){
                    case SET_RT_DEVICE_INFO: tcpService.setRT_DeviceInfo(ctx,task.getValues());break;
                    case ADD_RF_ClothSheetDetail: {
                        r_clothSheetDetail = tcpService.addRF_ClothSheetDetail(task.getValues());
                        break;
                    }
                    case EDIT_OR_ADD_RF_ClothSheet: tcpService.editOrAddRF_ClothSheet(task.getValues());break;
                    case GET_CLOTH_INFO:  {
                        encoder.encode(tcpService.getClothInfo(task.getValues()));
                        hasMessage = true;
                        break;
                    }
                    case ClothSheetDetail:{
                        tcpService.addRF_ClothSheetDetail(r_clothSheetDetail,task.getValues());
                        break;
                    }

                    case CHECK_UPDATE: {
                        encoder.encode(tcpService.checkUpdate(task.getValues()));
                        hasMessage = true;
                        break;
                    }

                    case EQUIPMENT_MODEL:
                    {
                        tcpService.equioment_model(ctx,task.getValues());
                        break;
                    }
                    case OTA_UPDATE_SUCCESS:{
                        otaController.sendEvent(task.getValues(),ctx);
                        break;
                    }
                    case GET_MES_CAMERA:{
                        encoder.encode(tcpService.getMESCamera());
                        hasMessage = true;
                        break;
                    }
                    case BATTERY_STATUS:
                    case EQUIPMENT_SERIAL:
                    case FIRMWARE_VERSION:
                    case DEVICE_STATUS:
                    case USER_AUTHENTICATION:


                    default: break;
                }
            } else if (type==ProtocolMessageTypeEnum.DATA_PASSTHROUGH_PACKET) {
                switch (task.getOption()){
                    case GET_MES_SWITCH_DETECTION:{
                        encoder.encode(tcpService.getMESSwitchDetection());
                        hasMessage = true;
                        break;
                    }
                    case SEND_EQUIPMENT_SERIAL:{
                        tcpService.saveEquipmentSerial(ctx,task.getValues());
                        break;
                    }
                    case GET_MES_IMAGE_REPORT:{
                        encoder.encode(tcpService.getMESImageReport());
                        hasMessage = true;
                        break;
                    }

                }
            }
        }
        if(hasMessage){
            return encoder.getMessage();
        }
        return response;
    }
}
